package game.components;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseEvent;

import javax.swing.JLabel;
import javax.swing.JPanel;

import remote.GameActionIfc;
import app.ui.PlayAreaPanel;
import app.ui.PlayingScreenUi;

public class GameAction implements GameActionIfc {
	protected PlayingScreenUi mPanel;
	protected PlayAreaPanel playAreaPanel;
	private RuleOfGame ruleOfGame;

	private int oldX = 0, oldY = 0;
	private int xDisp = 0;
	private int yDisp = 0;
	private int cellSize;
	private int frameX, frameY;

	public GameAction(PlayingScreenUi mPanel) {
		this.mPanel = mPanel;
		this.playAreaPanel = mPanel.getPlayAreaPanel();
		this.ruleOfGame = getAppUtilities().getRuleOfGame();

		this.cellSize = getAppUtilities().getCellSize();
	}

	public void mousePressed(MouseEvent e) {
		oldX = e.getX();
		oldY = e.getY();
		if (e.getSource() instanceof PlayAreaPanel) {
			xDisp = playAreaPanel.getxDisp();
			yDisp = playAreaPanel.getyDisp();
			frameX = mPanel.getmFrame().getX();
			frameY = mPanel.getmFrame().getY();
		}
	}

	public void mouseDragged(MouseEvent e) {
		// set cursor
		Component component = (Component) e.getSource();
		if (component.getCursor() != Cursor
				.getPredefinedCursor(Cursor.MOVE_CURSOR)) {
			component.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
		}

		// do moving
		if (e.getSource() instanceof PlayAreaPanel) {
			// doMoving(e);
		} else if (e.getSource() instanceof PlayingScreenUi) {
			doMovingApp(e);
		}
	}

	public void mouseClicked(MouseEvent e) {

	}

	public void mouseMoved(MouseEvent e) {
		Component component = (Component) e.getSource();
		if (e.getSource() instanceof PlayAreaPanel
				&& getAppUtilities().isGameStatus()) {
			Point p = doGetCurPos(e);
			if (!playAreaPanel.isScrolling()) {
				playAreaPanel.setCurMouLoc(p);
			}
			if (component.getCursor() != Cursor
					.getPredefinedCursor(Cursor.HAND_CURSOR)) {
				component.setCursor(Cursor
						.getPredefinedCursor(Cursor.HAND_CURSOR));
			}
		}
	}

	public void mouseReleased(MouseEvent e) {
		Object obj = e.getSource();
		// set cursor
		Component component = (Component) e.getSource();
		if (component instanceof JPanel) {
			component.setCursor(Cursor
					.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		}

		if (obj instanceof JLabel) {
			JLabel jLabel = (JLabel) obj;

			// close
			if (jLabel.getText().equals(mPanel.getLbl_text()[0])) {
				getAppUtilities().saveSession();
				System.exit(1);
			}
			// new game
			if (jLabel.getText().equals(mPanel.getLbl_text()[11])) {
				mPanel.startNewGame(getAppUtilities().getTurnOfPlayer());
			}
			// pause game
			else if (jLabel.getText().equals(mPanel.getLbl_text()[12])) {
				mPanel.pausingGame();
			}

			return;
		}

		//
		doPlaying(e);
		playAreaPanel.setScrolling(false);
	}

	protected void doScrollPlayArea(MouseEvent e) {
		int deltaX = (e.getX() - oldX) / 2;
		int deltaY = (e.getY() - oldY) / 2;

		playAreaPanel.adjustXY_disp(xDisp - deltaX, yDisp - deltaY);
	}

	/**
	 * [--- + -- ] / [_]
	 * 
	 * @param e
	 *            MouseEvent
	 * @return location of mouse pointing on the table
	 */
	protected Point doGetCurPos(MouseEvent e) {
		int x = (e.getX() + xDisp) / cellSize;
		int y = (e.getY() + yDisp) / cellSize;

		Point p = new Point(x, y);
		return p;
	}

	protected void doPlaying(MouseEvent e) {
		boolean isGameStart = getAppUtilities().isGameStatus();

		if (e.getSource() instanceof PlayAreaPanel && isGameStart) {
			// ad point location to player's moving
			Point p = doGetCurPos(e);
			Player winner = getAppUtilities().getWinner();

			// If the point has already existed on moving then doing nothing
			if (ruleOfGame.checkExistedPoint(p) || winner != null) {
				return;
			}

			Player player = getAppUtilities().getTurnOfPlayer();

			// Check the privilege of player
			if (getAppUtilities().isMultiPlayer()) {
				if (getAppUtilities().getPlayerID() != player.getID()) {
					return;
				}
			}

			player.addMoving(p);

			playAreaPanel.setLasMovLoc(p);
			playAreaPanel.repaint();

			mPanel.setPlayerTurn(); // change turn of Player
		}
	}

	protected void doMovingApp(MouseEvent e) {
		frameX += e.getX() - oldX;
		frameY += e.getY() - oldY;

		mPanel.getmFrame().setLocation(frameX, frameY);
	}

	public AppUtilities getAppUtilities() {
		return mPanel.getmFrame().getAppUtilities();
	}
}
